﻿// <copyright file="PlayerImporter.cs" company="Gravity Age Studios">
// Code released under the MIT license (see License.txt).
// </copyright>
// <author>Vicente Cartas Espinel</author>
// <email>vicente.cartas@gmail.com</email>
namespace LightSwitchApplication.Import
{
    using System;
    using System.Linq;
    using Microsoft.LightSwitch;
    using Microsoft.LightSwitch.Security;

    internal class PlayerImporter : VisualCollectionImporter<Player>
    {
        private readonly int Visibility = 0;
        private readonly int UserName = 1;
        private readonly int RealName = 2;
        private readonly int Email = 3;
        private readonly int PublicInformation = 4;
        private readonly int GMInformation = 5;

        public PlayerImporter(DataWorkspace workspace)
            : base(workspace)
        {
        }

        protected override bool SkipEntity(int index)
        {
            if (this.headers[UserName].HasValue)
            {
                if (this.entities.Any(e => e.UserName.Equals(data[index + headers[UserName].Value].Trim(), StringComparison.InvariantCultureIgnoreCase)))
                {
                    return true;
                }
            }

            return false;
        }

        protected override int?[] MapHeaders(string[] stringHeaders)
        {
            int?[] headers = new int?[6];

            for (int i = 0; i < stringHeaders.Length; i++)
            {
                if (stringHeaders[i].StartsWith("Vis", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Visibility] = i;
                }
                else if (stringHeaders[i].StartsWith("User", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[UserName] = i;
                }
                else if (stringHeaders[i].StartsWith("Name", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[RealName] = i;
                }
                else if (stringHeaders[i].StartsWith("Email", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[Email] = i;
                }
                else if (stringHeaders[i].StartsWith("Public", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[PublicInformation] = i;
                }
                else if (stringHeaders[i].StartsWith("GM", StringComparison.InvariantCultureIgnoreCase))
                {
                    headers[GMInformation] = i;
                }
            }

            return headers;
        }

        protected override void FillEntity(Player entity, int index, int?[] headers, string[] data)
        {
            if (!headers[UserName].HasValue && !headers[RealName].HasValue)
            {
                return;
            }

            if (headers[Visibility].HasValue)
            {
                int value;
                if (int.TryParse(data[index + headers[Visibility].Value], out value))
                {
                    entity.Visibility = value;
                }
            }

            if (headers[UserName].HasValue)
            {
                entity.UserName = data[index + headers[UserName].Value];
            }

            if (headers[RealName].HasValue)
            {
                entity.RealName = data[index + headers[RealName].Value];
            }

            if (headers[Email].HasValue)
            {
                entity.Email = data[index + headers[Email].Value];
            }

            if (headers[PublicInformation].HasValue)
            {
                entity.PublicInformation = data[index + headers[PublicInformation].Value];
            }

            if (headers[GMInformation].HasValue)
            {
                entity.GMInformation = data[index + headers[GMInformation].Value];
            }

            this.CreateUser(entity.UserName, entity.RealName);
        }

        private void CreateUser(string userName, string realName)
        {
            UserRegistration user = null;

            // Check if there is an existing User with this UserName in the DB
            user = this.workspace.SecurityData.UserRegistrations
                .Where(u => u.UserName.Equals(userName, StringComparison.InvariantCultureIgnoreCase))
                .FirstOrDefault();

            if (user == null) // We are creating a new Player, so create a new User associated with it
            {
                // There wasn't a User with the selected UserName, so create one that will use the Player data
                user = this.workspace.SecurityData.UserRegistrations.AddNew();
                user.UserName = userName;
                user.FullName = realName;
                user.Password = "changeme/123";

                // Assume new users are Players and try to give them the correct role
                var role = this.workspace.SecurityData.Roles.
                    Where(r => r.Name.Equals("Player", StringComparison.InvariantCultureIgnoreCase))
                    .FirstOrDefault();

                if (role != null)
                {
                    var assign = new RoleAssignment();
                    assign.Role = role;
                    user.RoleAssignments.Add(assign);
                }
            }
            else // We are editing the Player, or the User already existed, check that Player.RealName and User.FullName are sync'ed
            {
                if (!user.FullName.Equals(realName, StringComparison.InvariantCultureIgnoreCase))
                {
                    user.FullName = realName;
                }
            }

            this.workspace.SecurityData.SaveChanges();
        }
    }
}
